﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using pigs;

namespace Pigs.Enemies
{
    class Magic_Pig : pigs.Pig
    {
        public Vector2 teleportTo;
        public Boolean teleporting;
        float scale;
        public int timer;

        public Texture2D magicPigTexture;

        // Animation variables
        int frameCount = 0; // Current frame
        int frameSkipX = 124; // Width of a frame
        int animationCount; // How many ticks since the last frame change.
        int animationMax; // How many ticks to change frame after. 
        Rectangle source;

        /// <summary>
        /// make the new pig
        /// </summary>
        /// <param name="texture">texture to use</param>
        /// <param name="position">where should the pig start out</param>
        public Magic_Pig(Texture2D texture, Vector2 position, int numPlayers)
            : base(texture, position)
        {
            START_HEALTH = 3;
            START_DAMAGE = 10;
            START_SPEED = 2f;
            VALUE = 200;

            this.position = position;
            this.magicPigTexture = texture;
            this.active = true; // We initialize the enemy to be active so it will be update in the game
            this.health = START_HEALTH * numPlayers;
            if (numPlayers == 1) { this.damage = this.START_DAMAGE + 5; }
            else if (numPlayers > 2 && numPlayers < 5) { this.damage = this.START_DAMAGE + 10; }
            else { this.damage = this.START_DAMAGE * 3; }
            this.speed = START_SPEED;
            this.value = VALUE;
            this.effect = SpriteEffects.None;
            this.ID = "magic";
            this.teleporting = false;
            this.scale = 1;
            this.timer = 100;
            this.lead = false;
            this.buff = false;
            this.escaped = false;
            this.hitByFlame = false;
            this.ghost = false;
            this.shouldEatSlop = true;

            // Start with frame 1 of image array
            this.frameCount = 1;
            this.animationCount = 0;
            this.animationMax = 3;

            this.source = new Rectangle(this.frameSkipX * this.frameCount, 0, this.frameSkipX, this.texture.Height);

            rectangle = new Rectangle((int)position.X, (int)position.Y, source.Width, source.Height);

            //get the color data
            colorMap = new Color[source.Width * source.Height];
            this.texture.GetData(0, source, colorMap, 0, source.Width * source.Height);
        }

        /// <summary>
        /// The AI for a magic pig
        /// </summary>
        /// <param name="obstacles"></param>
        /// <param name="players"></param>
        /// <param name="time"></param>
        /// <param name="pigs"></param>
        public void doAI(List<Scenery> obstacles, List<Player> players, GameTime time, List<pigs.Pig> pigs, bool steelPigPresent)
        {
            // If the magic pig gets a leader buff double its current health and damage
            if (this.lead && !this.buff)
            {
                this.health *= 2;
                this.damage *= 2;
                this.buff = true;
            }
            // Avoid suicide pigs
            avoidSuicide(pigs, obstacles);
            // Teleport away from players to a random location if they get too close
            foreach (Player p in players)
            {
                if (Math.Abs(Vector2.Distance(p.center(), center())) < (p.rectangle.Width + (this.texture.Width / 5) + 100/players.Count))
                {
                    Random r = new Random(time.TotalGameTime.Seconds);
                    teleporting = true;
                    teleportTo = new Vector2(r.Next(500, 1000), r.Next(30, 768));
                    Vector2 storePosition = position;
                    position = teleportTo;

                    Boolean clear = false;
                    while (!clear)
                    {
                        foreach (Scenery s in obstacles)
                        {
                            if (p.checkCollision(s))
                            {
                                teleportTo = new Vector2(r.Next(500, 1000), r.Next(30, 768));
                                position = teleportTo;
                                break;
                            }
                        }
                        clear = true;
                    }

                    position = storePosition;
                    break;
                }
            }

            SteelPig tmp = new SteelPig(this.texture, this.position);
            int first = 0;
            foreach (Pig p in pigs)
            {
                if (p.ID.Equals("magic"))
                {
                    if (p == this && first == 0)
                    {
                        first = 1;
                    }
                    else if (first == 1) { }
                    else
                    {
                        first = 2;
                    }
                }
            }
            foreach (Pig p in pigs)
            {
                if (p.ID.Equals("steel"))
                {
                    tmp = (SteelPig) p;
                }
                if (first == 1)
                {
                    if (!p.ghost)
                    {
                        if (steelPigPresent)
                        {
                            if (p.ID.Equals("leader") || p.ID.Equals("ninja"))
                            {
                                if ((this.position.X - p.position.X) > 200 && p.speed > -1)
                                {
                                    p.speed -= 0.1f;
                                }
                                if ((this.position.Y - p.position.Y) > 100)
                                {
                                    if (p.ObstacleMove(obstacles, "down", p.position).Equals("none"))
                                    {
                                        p.position.Y += 3;
                                    }
                                }
                                else if ((this.position.Y - p.position.Y) < -100)
                                {
                                    if (p.ObstacleMove(obstacles, "up", p.position).Equals("none"))
                                    {
                                        p.position.Y -= 3;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (this.speed < this.START_SPEED) { this.speed += 0.1f; }
                            if (p.ID.Equals("leader") || p.ID.Equals("ninja") || p.ID.Equals("basic"))
                            {
                                if ((this.position.X - p.position.X) > 200 && p.speed > -1)
                                {
                                    p.speed -= 0.1f;
                                }
                                if ((this.position.Y - p.position.Y) > 100)
                                {
                                    if (p.ObstacleMove(obstacles, "down", p.position).Equals("none"))
                                    {
                                        p.position.Y += 3;
                                    }
                                }
                                else if ((this.position.Y - p.position.Y) < -100)
                                {
                                    if (p.ObstacleMove(obstacles, "up", p.position).Equals("none"))
                                    {
                                        p.position.Y -= 3;
                                    }
                                }
                            }
                        }
                    }
                }

                // If the timer is done make each nearby pig ghostly
                // If the pig has received the leader buff, then heal other nearby pigs
                // And reset the timer
                if (this.timer == 0)
                {
                    if (Vector2.Distance(this.position, p.position) < 300)
                    {
                        p.makeGhost();
                        p.ghost = true;
                        if (this.buff)
                        {
                            p.health += 3;
                        }
                    }
                }
            }

            if (steelPigPresent)
            {
                this.followSteel(tmp);
            }
            else
            {
                this.shouldEatSlop = true;
                this.gohome(obstacles);
            }

            if (this.timer == 0) { this.timer = 200; }
            this.timer -= 1;
            if (this.health <= 0)
            {
                // By setting the Active flag to false, the game will remove this object from the 
                // active game list
                this.active = false;
            }
            this.position.X -= speed;
        }
        
        /// <summary>
        /// update for the magic pig
        /// </summary>
        /// <param name="gameTime"></param>The current game time
        /// <param name="obstacles"></param>The list of obstacles
        /// <param name="players"></param>The list of players
        /// <param name="pigs"></param>The list of other pigs
        public override void magicUpdate(GameTime gameTime, List<Scenery> obstacles, List<Player> players, List<pigs.Pig> pigs, bool steelPigPresent)
        {
            if (this.shouldGhost && this.color.A > 70)
            {
                this.color.A--;
                this.color.A--;
                this.color.A--;
            }


            // If this pig is teleporting shrink it and move it
            if (teleporting)
            {
                if (scale == 1) scale = 0;
                scale += .05f;
                if (scale >= 1)
                {
                    scale = 1;
                    teleporting = false;
                    this.position = teleportTo;
                }
            }
            // Otherwise its normal scenery avoidance
            else
            {
                if (!this.avoidScenery(obstacles))
                {
                    doAI(obstacles, players, gameTime, pigs, steelPigPresent);
                }
            }

            rectangle = new Rectangle((int)position.X, (int)position.Y, source.Width, source.Height);
            UpdateAnimation();
        }

        // Perform the animation updates on the image
        public void UpdateAnimation()
        {
            this.animationCount += 1;
            if (this.animationCount > this.animationMax)
            {
                this.animationCount = 0;
                this.frameCount += 1;
                if (this.frameCount == 5)
                {
                    this.frameCount = 0;
                }
            }
        }

        /// <summary>
        /// An override draw function for the mag pig due to its teleporting nature
        /// </summary>
        /// <param name="spriteBatch"></param>
        public override void Draw(SpriteBatch spriteBatch)
        {
            if (teleporting)
            {
                // Update the source rectangle, based on where in the animation we are.  
                this.source.X = this.frameSkipX * this.frameCount;
                spriteBatch.Draw(texture, this.position, this.source, color, 0f, Vector2.Zero, 1f - scale, effect, 0f);
                spriteBatch.Draw(texture, this.teleportTo, this.source, color, 0f, Vector2.Zero, scale, effect, 0f);
            }
            else
            {
                // Update the source rectangle, based on where in the animation we are.  
                this.source.X = this.frameSkipX * this.frameCount;
                spriteBatch.Draw(texture, this.position, this.source, color, 0f, Vector2.Zero, 1f, effect, 0f);
            }
        }
    }
}
